// sem_demo.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#define SEM_KEY 1234

union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};

int sem_create(key_t key) {
    int semid = semget(key, 1, IPC_CREAT | 0666);
    if (semid == -1) {
        perror("semget");
        exit(1);
    }
    union semun arg;
    arg.val = 0;
    if (semctl(semid, 0, SETVAL, arg) == -1) {
        perror("semctl");
        exit(1);
    }
    return semid;
}

void sem_p(int semid) {
    struct sembuf op = {0, -1, SEM_UNDO};
    if (semop(semid, &op, 1) == -1) {
        perror("semop");
        exit(1);
    }
}

void sem_v(int semid) {
    struct sembuf op = {0, 1, SEM_UNDO};
    if (semop(semid, &op, 1) == -1) {
        perror("semop");
        exit(1);
    }
}

int main() {
    int semid = sem_create(SEM_KEY);
    pid_t pid = fork();

    if (pid == 0) { // 子进程
        sleep(1);
        sem_v(semid);
        printf("Child process done\n");
    } else { // 父进程
        sem_p(semid);
        printf("Parent process done\n");
    }

    semctl(semid, 0, IPC_RMID); // 删除信号量
    return 0;
}
